<script lang="ts" setup>
interface TopBtn {
  name: string;
  disabled: boolean;
  label: string;
  type: string;
  icon: string;
}
interface TreeProps {
  children: 'children';
  hasChildren: 'hasChildren';
}
interface Column {
  prop: string;
  label: string;
  align: 'center' | 'left' | 'right';
  width: number;
}
interface Tag extends Column {
  type: 'tag';
  active: {
    type: string;
    title: string;
    value: string;
  };
  inactive: {
    type: string;
    title: string;
    value: string;
  };
}
interface Swtich extends Column {
  type: 'switch';
  disabled: boolean;
  style?: string;
  active: string;
  inactive: string;
}
interface select extends Column {
  type: 'select';
}
interface Computedt extends Column {
  type: 'computedt';
  option: any;
}
interface operate {
  label: string;
  type: string;
  name: string;
}
type Columns = Tag | Swtich | select | Computedt;
export interface Props {
  topBtn?: Array<TopBtn>;
  divider?: boolean;
  datas?: Array<any>;
  treeProps?: TreeProps;
  selection?: boolean;
  serial?: boolean;
  columns?: Array<Columns>;
  operates?: Array<operate>;
}
const props = withDefaults(defineProps<Props>(), {
  topBtn: () => [] as Array<TopBtn>,
  divider: false,
  datas: () => [] as Array<any>,
  treeProps: () => ({ children: 'children', hasChildren: 'hasChildren' }),
  selection: false,
  serial: false,
  columns: () => [] as Array<Columns>,
  operates: () => [],
});
const emit = defineEmits([
  'tableClick',
  'tableSelect',
  'switchChange',
  'tableButton',
]);
const ElSwitchRef: Ref<any> = ref(null);
const switchLoding: Ref<boolean[]> = ref([]);
const tableRef: Ref = ref();

/** 表格点击事件 */
const tableHandleClick = (scope: any) => {
  emit('tableClick', toRaw(scope.row), toRaw(scope.$index));
};

/** 表格选择事件 */
const tableSelectionChange = (val) => {
  emit('tableSelect', val);
};

/** 表格按钮点击事件 */
const buttonClick = (scope) => {
  emit('tableButton', toRaw(scope));
};

const selectComputedt = (value: string, option: any) => {
  return option[value];
};

/** 表格开关点击事件 */
const handleSwitchChange = (scope) => {
  switchLoding.value[scope.$index] = true;
  emit('switchChange', scope.row);
  setTimeout(() => {
    switchLoding.value[scope.$index] = false;
  }, 2000);
};

/** 表格按钮点击事件 */
const tableButton = (row, item) => {
  if (item.confirm) {
    promptBox(item.title, () => {
      emit('tableButton', row, item);
    });
  } else {
    emit('tableButton', row, item);
  }
};
const promptBox = (title: string, fun: any) => {
  ElMessageBox.confirm(title, '提示', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning',
  })
    .then(() => {
      fun && fun();
    })
    .catch(() => {});
};
const clearSelect = () => {
  tableRef.value.clearSelection();
};
defineExpose({
  clearSelect,
});
</script>

<template>
  <div>
    <span v-if="props.topBtn">
      <el-button
        v-for="(item, index) in props.topBtn"
        :key="index"
        :icon="item.icon"
        :type="item.type"
        :disabled="item.disabled"
        @click="buttonClick(item)"
      >
        {{ item.label }}
      </el-button>
    </span>
    <el-divider v-if="props.divider" />
    <el-table
      ref="tableRef"
      :data="props.datas"
      style="width: 100%"
      :tree-props="props.treeProps"
      @selection-change="tableSelectionChange"
    >
      <el-table-column
        v-if="props.selection"
        :reserve-selection="props.selection"
        type="selection"
        width="35"
      />
      <el-table-column
        v-if="props.serial"
        type="index"
        label="序号"
        align="center"
        width="55"
      />
      <el-table-column
        v-for="(item, index) in props.columns"
        :key="index"
        :prop="item.prop"
        :label="item.label"
        :align="item.align"
        :show-overflow-tooltip="true"
        :width="item.width"
        min-width="140"
      >
        <template #default="scope">
          <span @click="tableHandleClick(scope)">
            <span v-if="item.type === 'computedt'">
              {{ selectComputedt(scope.row[item.prop], item.option) }}
            </span>
            <span v-if="item.type === 'select'">
              <el-select></el-select>
            </span>
            <span v-if="item.type === 'tag'">
              <el-tag
                :type="
                  scope.row[item.prop] == item.active.value
                    ? item.active.type
                    : item.inactive.type
                "
              >
                {{
                  scope.row[item.prop] == item.active.value
                    ? item.active.title
                    : item.inactive.title
                }}
              </el-tag>
            </span>
            <span v-if="item.type === 'switch'">
              <el-switch
                ref="ElSwitchRef"
                v-model="scope.row[item.prop]"
                :disabled="item.disabled === undefined ? true : item.disabled"
                :style="item.style"
                :active-value="item.active"
                :inactive-value="item.inactive"
                :loading="switchLoding[scope.$index]"
                @change="handleSwitchChange(scope)"
              />
            </span>
            <span v-if="item.type == undefined">
              {{ scope.row[item.prop] }}
            </span>
          </span>
        </template>
      </el-table-column>
      <el-table-column
        v-if="props.operates.length > 0"
        label="操作"
        :width="'200'"
        fixed="right"
      >
        <template #default="scope: any">
          <span v-for="(item, index) in props.operates" :key="index">
            <el-button
              link
              :type="item.type ? item.type : ''"
              @click="tableButton(scope.row, item)"
            >
              {{ item.label }}
            </el-button>
            <el-divider
              v-if="index < props.operates.length - 1"
              direction="vertical"
            />
          </span>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>
